﻿using System;
using System.Collections.Generic;

using System.Text;
/**************************
 * NOTE: This code was taken from Jon Galloway's
 *  article on ASP.NET: http://weblogs.asp.net/jgalloway/archive/2008/04/13/encrypting-passwords-in-a-net-app-config-file.aspx
 *  
 * This code has been modified to use normal strings, instead of SecureStrings - since I'm not too concerned about the password being read from memory
 **************************/
namespace P3SS.Security
{
	/// <summary>
	/// Handles the encryption and decryption of strings
	/// </summary>
	public class EncryptionHandler
	{
		const string ENTROPY = "Salt Is Not A Password";

		/// <summary>
		/// Encrypts string using default Salt. This function is not recommended as each string should use its own Salt
		/// </summary>
		/// <param name="input">String the encrypt (Plaintext)</param>
		/// <returns>Encrypted string (Crypttext)</returns>
		public static string EncryptString(string input)
		{
			return EncryptString(input, ENTROPY);
		}

		/// <summary>
		/// Encrypts string using the given salt
		/// </summary>
		/// <param name="input">String the encrypt (Plaintext)</param>
		/// <param name="salt">A unique, but not secure, string to prevent replay attacks. Timestamps are a good idea. This string is needed for decryption.</param>
		/// <returns>Encrypted string (Crypttext)</returns>
		public static string EncryptString(string input, string salt)
		{
			byte[] encryptedData = System.Security.Cryptography.ProtectedData.Protect(
				System.Text.Encoding.Unicode.GetBytes(input),
				Encoding.UTF8.GetBytes(salt),
				System.Security.Cryptography.DataProtectionScope.LocalMachine);
			return Convert.ToBase64String(encryptedData);
		}

		/// <summary>
		/// Decrypts a previously encrypted string using the default salt. Only use this function if the string was encrypted with the default salt
		/// </summary>
		/// <param name="encryptedData">String to decrypt (Crypttext)</param>
		/// <returns>Original string (plaintext)</returns>
		public static string DecryptString(string encryptedData)
		{
			return DecryptString(encryptedData, ENTROPY);
		}

		/// <summary>
		/// Decrypts a previously encrypted string using the default salt. Only use this function if the string was encrypted with the default salt
		/// </summary>
		/// <param name="encryptedData">String to decrypt (Crypttext)</param>
		/// <param name="salt">The salt used when encrypting</param>
		/// <returns>Original string (plaintext)</returns>
		public static string DecryptString(string encryptedData, string salt)
		{
			string outString = "";
			try
			{
				byte[] decryptedData = System.Security.Cryptography.ProtectedData.Unprotect(
					Convert.FromBase64String(encryptedData),
					Encoding.UTF8.GetBytes(salt),
					System.Security.Cryptography.DataProtectionScope.LocalMachine);
				outString = System.Text.Encoding.Unicode.GetString(decryptedData);
			}
			catch
			{ }

			return outString;
		}
	}
}
